#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "SDL/SDL.h"
#include "SDL/SDL_draw.h"
#include "SDL_Button.h"
#include "util.h"
#include "stack.h"

SDL_Surface *screen;
Button button[25];
SDL_Event event;
TTF_Font *font;
SDL_Surface *expression;
SDL_Surface *expression2;
SDL_Color textColor = {0, 0, 0};
char buffer[50];
char render[50];

//渲染
void render_to_screen(char *render)
{
    Draw_FillRect(screen, 10, 10, 590, 110, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
    expression = TTF_RenderUTF8_Solid(font, render, textColor);
    apply_surface(screen->w - expression->w - 20, 100 - expression->h, expression, screen);
    SDL_Flip(screen);
}

void on_mouse_click(Button *button)
{
    //普通按钮点击的回调函数
    strcat(buffer, button->text);
    strcat(render, button->text);
    render_to_screen(render);
}

void on_AC_click(Button *button)
{
    //AC点击回调函数
    memset(buffer, 0, sizeof(buffer));
    memset(render, 0, sizeof(render));
    render_to_screen("0");
}

void on_equal_click(Button *button)
{
    //计算
    char s[50]; //用于存储转换后的表达式
    int i;
    for (i = 0; buffer[i] != '\0'; i++)
    {
        if ((buffer[i] >= '0' && buffer[i] <= '9') || buffer[i] == '.')
        {
            continue;
        }
        else
            break;
    }
    if (buffer[i] == '\0')
    {
        Draw_FillRect(screen, 10, 10, 590, 110, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
        expression = TTF_RenderUTF8_Solid(font, double_to_string(atof(buffer), 2), textColor);
    }
    else
    {
        i = 0;
        if (judge_infix(buffer)) //判断输入合法性
        {
            Transform(buffer, s); //处理字符串，并转化为后缀表达式,存放在s中
            Draw_FillRect(screen, 10, 10, 590, 110, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
            expression = TTF_RenderUTF8_Solid(font, double_to_string(Calculate(s), 2), textColor);
        }
        else
        {
            Draw_FillRect(screen, 10, 10, 590, 110, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
            expression = TTF_RenderUTF8_Solid(font, "表达式错误", textColor);
        }
    }
    expression2 = TTF_RenderUTF8_Solid(font, strcat(render, "="), textColor);
    //清空缓冲区和渲染区
    memset(buffer, 0, sizeof(buffer));
    memset(render, 0, sizeof(render));
    apply_surface(20, 20, expression2, screen);
    apply_surface(screen->w - expression->w - 20, 100 - expression->h, expression, screen);
    SDL_Flip(screen);
}

void on_power_click(Button *button)
{
    strcat(buffer, "^");
    strcat(render, "²");
    render_to_screen(render);
}

void on_multiple_click(Button *button)
{
    strcat(buffer, "*");
    strcat(render, "×");
    render_to_screen(render);
}

void on_division_click(Button *button)
{
    strcat(buffer, "/");
    strcat(render, "÷");
    render_to_screen(render);
}

void on_sqrt_click(Button *button)
{
    strcat(buffer, "$");
    strcat(render, "√");
    render_to_screen(render);
}

void on_sin_click(Button *button)
{
    strcat(buffer, "s(");
    strcat(render, "sin(");
    render_to_screen(render);
}

void on_cos_click(Button *button)
{
    strcat(buffer, "c(");
    strcat(render, "cos(");
    render_to_screen(render);
}

void on_tan_click(Button *button)
{
    strcat(buffer, "t(");
    strcat(render, "tan(");
    render_to_screen(render);
}

void init_View()
{
    button[0] = SDL_Button(10, 310, 80, 50, ".", font);
    button[1] = SDL_Button(95, 310, 80, 50, "0", font);
    button[2] = SDL_Button(180, 310, 80, 50, "%", font);
    button[3] = SDL_Button(10, 250, 80, 50, "1", font);
    button[4] = SDL_Button(95, 250, 80, 50, "2", font);
    button[5] = SDL_Button(180, 250, 80, 50, "3", font);
    button[6] = SDL_Button(10, 190, 80, 50, "4", font);
    button[7] = SDL_Button(95, 190, 80, 50, "5", font);
    button[8] = SDL_Button(180, 190, 80, 50, "6", font);
    button[9] = SDL_Button(10, 130, 80, 50, "7", font);
    button[10] = SDL_Button(95, 130, 80, 50, "8", font);
    button[11] = SDL_Button(180, 130, 80, 50, "9", font);
    button[12] = SDL_Button(265, 310, 80, 50, "+", font);
    button[13] = SDL_Button(265, 250, 80, 50, "-", font);
    button[14] = SDL_Button(435, 190, 80, 50, "(", font);
    button[15] = SDL_Button(520, 190, 80, 50, ")", font);
    button[16] = SDL_Button(265, 190, 80, 50, "×", font);
    button[17] = SDL_Button(265, 130, 80, 50, "÷", font);
    button[18] = SDL_Button(520, 250, 80, 50, "√", font);
    button[19] = SDL_Button(435, 250, 80, 50, "x²", font);
    button[20] = SDL_Button(350, 310, 250, 50, "=", font);
    button[21] = SDL_Button(435, 130, 165, 50, "AC", font);
    button[22] = SDL_Button(350, 130, 80, 50, "sin", font);
    button[23] = SDL_Button(350, 190, 80, 50, "cos", font);
    button[24] = SDL_Button(350, 250, 80, 50, "tan", font);
}

int main()
{
    int quit = 0;
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    font = TTF_OpenFont("msyh.ttf", 25);
    if(font == NULL){
        printf("字体文件加载失败");
        return 1;
    }
    screen = SDL_SetVideoMode(610, 370, 32, SDL_SWSURFACE);
    SDL_WM_SetCaption("计算器", NULL);
    init_View();
    for (int i = 0; i < 25; i++)
    {
        set_button_to_screen(button + i, screen);
    }
    Draw_FillRect(screen, 10, 10, 590, 110, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
    SDL_Flip(screen);
    while (!quit)
    {
        while (SDL_PollEvent(&event))
        {
            for (int i = 0; i < 16; i++)
            {
                handle_button_events(button + i, event, on_mouse_click);
            }
            handle_button_events(button + 16, event, on_multiple_click);
            handle_button_events(button + 17, event, on_division_click);
            handle_button_events(button + 18, event, on_sqrt_click);
            handle_button_events(button + 19, event, on_power_click);
            handle_button_events(button + 20, event, on_equal_click);
            handle_button_events(button + 21, event, on_AC_click);
            handle_button_events(button + 22, event, on_sin_click);
            handle_button_events(button + 23, event, on_cos_click);
            handle_button_events(button + 24, event, on_tan_click);
            if (event.type == SDL_QUIT)
            {
                quit = 1;
            }
        }
    }
    for (int i = 0; i < 25; i++)
    {
        clean_Button(button + i);
    }
    SDL_Quit();
    return 0;
}